module Ele

    importall Geo, Sec
    export Element,
            Line, GeneralLine,
            Line2D, Line3D,
            ElasticTruss2D,
            getDofMatrix,
            setDeform, getStiff,
            getStiffMatrix, getMassMatrix, 
            getForce, getForceStiff 

    abstract Element
    abstract Line <: Element
    abstract Line2D <: Line
    abstract Line3D <: Line

    abstract CoordSystem

    type GlobalSystem <: CoordSystem
        I::Vector{Float64}
        J::Vector{Float64}
        K::Vector{Float64}

        function GlobalSystem(dim::Int64)
            if dim == 2
                I = [1.,0.]
                J = [0.,1.]
                K = [0.,0.]
            elseif dim == 3
                I = [1.,0.,0.]
                J = [0.,1.,0.]
                K = [0.,0.,1.]
            end
            return new(I,J,K)
        end
    end

    type LocalSystem <: CoordSystem
        
        I::Vector{Float64}
        J::Vector{Float64}
        K::Vector{Float64}

    	function LocalSystem(dim::Int64,I::Vector{Float64})
    		
    		if dim == 2
				J = [-I[2],I[1]]
				K = [0.,0.]
    		elseif dim == 3
    			gsys = GlobalSystem(dim)
    			if I == gsys.K
    				J = [0.,1.,0.]
    				K = [-1.,0.,0.]
			    else
			    	a_x,a_y,a_z = I
			    	ool = 1./sqrt(1.-a_z^2)
			    	J = [-a_x*a_z*ool,-a_y*a_z*ool,(1.-a_z^2)*ool]
			    	K = [a_y*ool,-a_x*ool,0]
			    end
    		end
    		return new(I,J,K)
    	end        
    end

    VECTX2D = [1.,0.]
    VECTY2D = [0.,1.]
    VECTX3D = [1.,0.,0.]
    VECTY3D = [0.,1.,0.]
    VECTZ3D = [0.,0.,1.]

    type GeneralLine <: Line
        
        tag::Int64 #// 标签
        NodeI::Node #// 节点I
        NodeJ::Node #// 节点J
        Sec::Section #// 单元截面

        GeneralLine(tag::Int64, NodeI::Node, NodeJ::Node, Sec::Section) = new(tag,NodeI,NodeJ,deepcopy(Sec))

    end

    # function GetLine2DGeo(NodeI::Node, NodeJ::Node)
        
    #     vecx = NodeJ.coord .- NodeI.coord
    #     len = norm(vecx)
    #     vecx = vecx/len
    #     vecy = [-vecx[2],vecx[1]]

    #     return len,vecx,vecy
    # end

    # function GetLine3DGeo(NodeI::Node, NodeJ::Node)
        
    #     vecx = NodeJ.coord .- NodeI.coord
    #     len = norm(vecx)
    #     vecx = vecx/len
    #     vecy = [-vecx[2],vecx[1]]

    #     return len,vecx,vecy
    # end    

    include("Ele/ElasticTruss2D.jl")

end
